from LogConfig import getLog
from UTIL import log_with_company, format_date, get_days_diff

logger = getLog("WE/RE凭证处理")

import pandas as pd
import datetime



def get_previous_previous_quarter(date):
    """使用pandas的Quarter对象获取上上季度的起始和结束日期"""
    # 将日期转换为pandas的Period对象，频率为季度
    q = pd.Period(date, freq='Q')

    # 获取上上季度
    prev_prev_q = q - 2

    # 获取上上季度的起始和结束日期
    start_date = prev_prev_q.start_time.normalize().to_pydatetime()
    end_date = prev_prev_q.end_time.normalize().to_pydatetime()

    return start_date, end_date


def process_we_re_vouchers(公司代码, df, current_date):
    """
    处理WE/RE类型凭证

    参数:
        公司代码: 公司代码字符串
        df: 包含所有凭证数据的DataFrame
        current_date: 当前日期，用于计算天数差

    返回:
        write_data: 需要写入的数据列表
    """
    log_with_company(公司代码, "info", "开始处理WE/RE类型凭证")

    # 筛选凭证类型为"WE"和"RE"的记录
    df_filtered = df[df['凭证类型'].isin(['WE', 'RE'])]
    log_with_company(公司代码, "info", f"WE/RE类型凭证共{len(df_filtered)}条")

    # 按"分配"列分组并计算本币金额总和，保留2位小数
    grouped = df_filtered.groupby('分配')['本币金额'].sum().round(2).reset_index()
    log_with_company(公司代码, "info", f"WE/RE类型凭证按分配分组后共{len(grouped)}组")

    write_data = []
    three_months_ago = current_date - datetime.timedelta(days=90)

    # 获取上上季度的起始和结束日期
    prev_prev_quarter_start, prev_prev_quarter_end = get_previous_previous_quarter(current_date)

    # 处理正数金额
    positive_amounts = grouped[grouped['本币金额'] > 0]
    log_with_company(公司代码, "info", f"WE/RE类型正数金额共{len(positive_amounts)}组")

    for _, row in positive_amounts.iterrows():
        小计金额 = row['本币金额']
        分配 = row['分配']
        original_records = df_filtered[df_filtered['分配'] == 分配]

        if 分配 == "450820887200001":
            a = 1
            print(1)

        # 按凭证日期降序排序，确保优先处理时间较早的记录
        original_records = original_records.sort_values('凭证日期', ascending=True)

        # 分离正负金额记录
        positive_records = original_records[original_records['本币金额'] > 0]
        negative_records = original_records[original_records['本币金额'] < 0]

        # 用于记录已处理的记录
        processed_positive = set()
        processed_negative = set()

        # 处理正负金额抵消
        for pos_idx, pos_record in positive_records.iterrows():
            for neg_idx, neg_record in negative_records.iterrows():
                # 如果金额相等且都未被处理过，则进行抵消
                if (abs(pos_record['本币金额']) == abs(neg_record['本币金额'])
                        and pos_idx not in processed_positive
                        and neg_idx not in processed_negative):
                    processed_positive.add(pos_idx)
                    processed_negative.add(neg_idx)
                    log_with_company(公司代码, "info",
                                     f'√ WE/RE类型凭证「{pos_record["凭证编号"]}」和「{neg_record["凭证编号"]}」金额抵消，金额：{pos_record["本币金额"]:.2f}')
                    break

        # 输出未抵消的记录
        for idx, record in original_records.iterrows():
            if idx in processed_positive or idx in processed_negative:
                continue  # 跳过已抵消的记录

            凭证类型 = record['凭证类型']
            客商名称 = record['客商名称']
            凭证编号 = record['凭证编号']

            write_data.append({
                '分组关键词': 分配,
                '凭证日期': format_date(record['凭证日期']),
                '凭证类型': record['凭证类型'],
                '凭证编号': 凭证编号,
                '客商名称': 客商名称,
                '本币金额': record['本币金额'],
                '文本': record['文本']
            })

    # 处理负数金额
    negative_amounts = grouped[grouped['本币金额'] < 0]
    log_with_company(公司代码, "info", f"WE/RE类型负数金额共{len(negative_amounts)}组")

    for _, row in negative_amounts.iterrows():
        小计金额 = row['本币金额']
        分配 = row['分配']

        original_records = df_filtered[df_filtered['分配'] == 分配]



        # 按凭证日期降序排序，确保优先处理时间较晚的记录
        original_records = original_records.sort_values('凭证日期', ascending=True)

        # 分离正负金额记录
        positive_records = original_records[original_records['本币金额'] > 0]
        negative_records = original_records[original_records['本币金额'] < 0]

        # 用于记录已处理的记录
        processed_positive = set()
        processed_negative = set()

        # 处理正负金额抵消
        for pos_idx, pos_record in positive_records.iterrows():
            for neg_idx, neg_record in negative_records.iterrows():
                # 如果金额相等且都未被处理过，则进行抵消
                if (abs(pos_record['本币金额']) == abs(neg_record['本币金额'])
                        and pos_idx not in processed_positive
                        and neg_idx not in processed_negative):
                    processed_positive.add(pos_idx)
                    processed_negative.add(neg_idx)
                    log_with_company(公司代码, "info",
                                     f'√ WE/RE类型凭证「{pos_record["凭证编号"]}」和「{neg_record["凭证编号"]}」金额抵消，金额：{pos_record["本币金额"]:.2f}')
                    break

        # 输出未抵消的记录
        for idx, record in original_records.iterrows():
            if idx in processed_positive or idx in processed_negative:
                continue  # 跳过已抵消的记录

            凭证类型 = record['凭证类型']
            客商名称 = record['客商名称']
            凭证编号 = record['凭证编号']
            voucher_date = pd.to_datetime(record['凭证日期'])

            if 分配 == "450820887200001":
                a = 1
                print(1)

            if 客商名称 == '国能易购（北京）科技有限公司':
                if voucher_date <= prev_prev_quarter_end:
                    log_with_company(公司代码, "error",
                                     f"×「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」金额「{record['本币金额']:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」早于上上季度末「{format_date(prev_prev_quarter_end)}」")
                    write_data.append({
                        '分组关键词': 分配,
                        '凭证日期': format_date(record['凭证日期']),
                        '凭证类型': record['凭证类型'],
                        '凭证编号': record['凭证编号'],
                        '客商名称': 客商名称,
                        '本币金额': record['本币金额'],
                        '文本': record['文本']
                    })
                else:
                    log_with_company(公司代码, "debug",
                                     f'√ 「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」金额「{record['本币金额']:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」晚于上上季度末「{format_date(prev_prev_quarter_end)}」')
                    continue

            elif voucher_date > three_months_ago:
                log_with_company(公司代码, "debug",
                                 f"√ 「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」金额「{record['本币金额']:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」距今不超过3个月")
                continue

            else:
                days_diff = get_days_diff(current_date, voucher_date)
                log_with_company(公司代码, "error",
                                 f'× 「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」金额「{record['本币金额']:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」距今「{days_diff}」天')
                write_data.append({
                    '分组关键词': 分配,
                    '凭证日期': format_date(record['凭证日期']),
                    '凭证类型': record['凭证类型'],
                    '凭证编号': record['凭证编号'],
                    '客商名称': 客商名称,
                    '本币金额': record['本币金额'],
                    '文本': record['文本']
                })

    return write_data

# def process_we_re_vouchers(公司代码, df, current_date):
#     """
#     处理WE/RE类型凭证
#
#     参数:
#         公司代码: 公司代码字符串
#         df: 包含所有凭证数据的DataFrame
#         current_date: 当前日期，用于计算天数差
#
#     返回:
#         write_data: 需要写入的数据列表
#     """
#     log_with_company(公司代码, "info", "开始处理WE/RE类型凭证")
#
#     # 筛选凭证类型为"WE"和"RE"的记录
#     df_filtered = df[df['凭证类型'].isin(['WE', 'RE'])]
#     log_with_company(公司代码, "info", f"WE/RE类型凭证共{len(df_filtered)}条")
#
#     # 按"分配"列分组并计算本币金额总和，保留2位小数
#     grouped = df_filtered.groupby('分配')['本币金额'].sum().round(2).reset_index()
#     log_with_company(公司代码, "info", f"WE/RE类型凭证按分配分组后共{len(grouped)}组")
#
#     write_data = []
#     three_months_ago = current_date - datetime.timedelta(days=90)
#
#     # 获取上上季度的起始和结束日期
#     prev_prev_quarter_start, prev_prev_quarter_end = get_previous_previous_quarter(current_date)
#
#     # 处理正数金额
#     positive_amounts = grouped[grouped['本币金额'] > 0]
#     log_with_company(公司代码, "info", f"WE/RE类型正数金额共{len(positive_amounts)}组")
#
#     for _, row in positive_amounts.iterrows():
#         小计金额 = row['本币金额']
#         分配 = row['分配']
#
#         # 获取该分配值对应的所有原始记录
#         original_records = df_filtered[df_filtered['分配'] == 分配]
#
#         # 遍历所有原始记录
#         for _, record in original_records.iterrows():
#             凭证类型 = record['凭证类型']
#             客商名称 = record['客商名称']
#             凭证编号 = record['凭证编号']  # 已经是字符串格式
#
#             # 写入所有记录，并添加分配作为分组关键词
#             write_data.append({
#                 '分组关键词': 分配,
#                 '凭证日期': format_date(record['凭证日期']),
#                 '凭证类型': record['凭证类型'],
#                 '凭证编号': 凭证编号,
#                 '客商名称': 客商名称,
#                 '本币金额': record['本币金额'],
#                 '文本': record['文本']
#             })
#
#     # 处理负数金额
#     negative_amounts = grouped[grouped['本币金额'] < 0]
#     log_with_company(公司代码, "info", f"WE/RE类型负数金额共{len(negative_amounts)}组")
#
#     for _, row in negative_amounts.iterrows():
#         小计金额 = row['本币金额']
#         分配 = row['分配']
#
#         original_records = df_filtered[df_filtered['分配'] == 分配]
#
#         # 遍历所有原始记录
#         for _, record in original_records.iterrows():
#             凭证类型 = record['凭证类型']
#
#             客商名称 = record['客商名称']
#             凭证编号 = record['凭证编号']  # 已经是字符串格式
#
#             # 转换凭证日期为datetime格式
#             voucher_date = pd.to_datetime(record['凭证日期'])
#             days_diff = get_days_diff(current_date, voucher_date)
#
#             if 客商名称 == '国能易购（北京）科技有限公司':
#
#                 if voucher_date <= prev_prev_quarter_end:
#                     log_with_company(公司代码, "error",
#                                      f"×「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」小计为负「{小计金额:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」早于上上季度末「{format_date(prev_prev_quarter_end)}」")
#                     # 写入所有记录，并添加分配作为分组关键词
#                     write_data.append({
#                         '分组关键词': 分配,
#                         '凭证日期': format_date(record['凭证日期']),
#                         '凭证类型': record['凭证类型'],
#                         '凭证编号': record['凭证编号'],
#                         '客商名称': 客商名称,
#                         '本币金额': record['本币金额'],
#                         '文本': record['文本']
#                     })
#                 else:
#                     log_with_company(公司代码, "debug",
#                                      f'√ 「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」小计为负「{小计金额:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」晚于上上季度末「{format_date(prev_prev_quarter_end)}」')
#                     continue
#
#
#
#             elif voucher_date > three_months_ago:
#
#                 # 1、先看是否3个月内入账，是的话，不提醒，不导出
#                 log_with_company(公司代码, "debug",
#                                  f"√ 「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」小计为负「{小计金额:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」距今不超过3个月")
#                 continue
#
#             else:
#                 log_with_company(公司代码, "error",
#                                  f'× 「{凭证类型}」凭证「{凭证编号}」，按分配「{分配}」小计为负「{小计金额:.2f}」，客商「{客商名称}」，凭证日期「{format_date(voucher_date)}」距今「{days_diff}」天')
#                 # 写入所有记录，并添加分配作为分组关键词
#                 write_data.append({
#                     '分组关键词': 分配,
#                     '凭证日期': format_date(record['凭证日期']),
#                     '凭证类型': record['凭证类型'],
#                     '凭证编号': record['凭证编号'],
#                     '客商名称': 客商名称,
#                     '本币金额': record['本币金额'],
#                     '文本': record['文本']
#                 })
#
#     return write_data
